using System;
using System.Net;
using System.IO;
using Silvery.Logs;

namespace Silvery.Loader
{
    public enum LaoderState
    {
        Ready, Downloading, Completed, Cancel,Error
    }
    /// <summary>
    /// 基本的下载读取方法
    /// </summary>
    public class BaseLoader : ILoader
    {
        WebClient webclient ;
        
        public LaoderState LaoderState { get; private set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        public BaseLoader()
        {
            this.LaoderState = Loader.LaoderState.Ready;
        }
        public BaseLoader(Uri uri)
        {
            this.LaoderState = Loader.LaoderState.Ready;
            LoadUri = uri;
        }
        /// <summary>
        /// 开始下载
        /// </summary>
        /// <param name="uri"></param>
        public void BeginDownLoad(Uri uri)
        {
            if (uri == null)
            {
                NErrorMessage.Current.Add("开始下载的Uri没有设置",this);
                return;
            }
            LoadUri = uri;
            
            if (Result != null)
            {
                LaoderState = Loader.LaoderState.Completed;
                
                this.LoadCompleted(Result);
                if (DownloadCompleted != null)
                    DownloadCompleted(this, null);
                return;
            }
            if (this.LaoderState != Loader.LaoderState.Ready)
                return;
            webclient = new WebClient();
            webclient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webclient_DownloadProgressChanged);
            webclient.OpenReadCompleted += new OpenReadCompletedEventHandler(webclient_OpenReadCompleted);
            webclient.OpenReadAsync(uri);
            
            LaoderState = Loader.LaoderState.Downloading;
        }
        /// <summary>
        /// 取消下载
        /// </summary>
        public void CancelDownload()
        {
            if (webclient == null)
                return;
            LaoderState = Loader.LaoderState.Cancel;
            webclient.CancelAsync();
        }
        /// <summary>
        /// 开始下载，需要指定LoadUri
        /// </summary>
        public void BeginDownLoad()
        {
            BeginDownLoad(LoadUri);
        }
        /// <summary>
        /// uri
        /// </summary>
        public Uri LoadUri { get; set; }
        /// <summary>
        /// 附加的信息
        /// </summary>
        public object AppendInfo { get; set; }
        IResStream result;
        /// <summary>
        /// 完成的内存
        /// </summary>
        public IResStream Result
        {
            get { return result; }
            set
            {
                result = value;
                
                    result.AddUsingTarget(this);
            }
        }
        /// <summary>
        /// 进程事件
        /// </summary>
        public event DownloadProgressChangedEventHandler DownloadProgressChanged;
        /// <summary>
        /// 下载完成事件
        /// </summary>
        public event OpenReadCompletedEventHandler DownloadCompleted;
        void webclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                LaoderState = Loader.LaoderState.Error;
                NErrorMessage.Current.Add("下载" + this.LoadUri.ToString() + "失败，原因是：" + e.Error.ToString(), this);
            }
            else
            {
                LaoderState = Loader.LaoderState.Completed;
                LoadCompleted(new ResStream(this.LoadUri, e.Result,this));
            }
            ClearWebClient();
            if (DownloadCompleted != null && LaoderState != Loader.LaoderState.Error)
                DownloadCompleted(this, e);
            
            
            
        }
        /// <summary>
        /// 下载完成方法，可以重载再处理
        /// </summary>
        /// <param name="stream"></param>
        protected virtual void LoadCompleted(IResStream stream)
        {
            Result = stream;
            if (Next != null)
                Next.BeginDownLoad();
            ClearWebClient();
        }
        void webclient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            if (DownloadProgressChanged != null)
                DownloadProgressChanged(this, e);
        }
        public ILoader Next { get; set; }

        #region IDisposable Members
        /// <summary>
        /// 清理WebClient
        /// </summary>
        protected virtual void ClearWebClient()
        {
            if (webclient != null)
            {
                webclient.DownloadProgressChanged -= webclient_DownloadProgressChanged;
                webclient.OpenReadCompleted -= webclient_OpenReadCompleted;
                webclient.CancelAsync();
                webclient = null;
            }
        }
        /// <summary>
        /// 销毁
        /// </summary>
        public virtual void Dispose()
        {
            ClearWebClient();
            DownloadProgressChanged = null;
            DownloadCompleted = null;
            if (Result != null)
            {
                Result.RemoveUsingTarget(this);
                Result = null;
            }
            Next = null;
            LoadUri = null;
        }

        #endregion


        public ITimer LoaderTimer { get; set; }
    }
}
